#include "MemoryCommunication.h"

MemoryCommunication::MemoryCommunication(Stream* _data)
{
	in_count = 0;
	stop_index = STD_STOPINDEX;

	out_read_index = 0;
	out_write_index = 0;

	available = true;
	do_write = false;

	Data = _data;
}

void MemoryCommunication::loop(){
	if(Data->available()){
		available = false;
		read_in = Data->read();
	}

	write_out = internal_loop(read_in,available, &do_write);
	if(do_write)
	{
		Data->write(write_out);
		do_write = false;
	}
	available = true;
}

byte MemoryCommunication::internal_loop(byte b, boolean read_only, boolean *do_write)  
{
	if(in_count == stop_index)
	{
		progress();
		reset();
	}
	if(!read_only){
		if(in_count == 1)
		{
			stop_index += b;
		}

		in_buffer[in_count++] = b;
	}
	if(out_read_index != out_write_index){
		*do_write = true;
		return out_buffer[out_read_index++];
	}
}

void MemoryCommunication::progress()
{
	int adress;
	byte methode_type = in_buffer[0];
	byte lenght = in_buffer[1];

	DEBUG("METHOD_TYPE:\t%d",methode_type);
	DEBUG("LENGHT:\t%d",lenght);

	switch (methode_type)
	{
	case METHODE_GET_SINGLE_VALUE:
		DEBUG("METHODE_GET_SINGLE_VALUE");

		adress = ((in_buffer[3]<<8)|in_buffer[4]);

		DEBUG("ADRESS: %d", adress);

		get_value(in_buffer[2], (byte*)adress);
		break;
	case METHODE_SET_SINGLE_VALUE:
		DEBUG("METHODE_SET_SINGLE_VALUE");

		adress = ((in_buffer[3]<<8)|in_buffer[4]);

		DEBUG("ADRESS: %d\r\n", adress);

		set_value(in_buffer[2], (byte*)adress);
		break;
	default:
		DEBUG("UNKNOWN_METHODE");
		break;
	}
}

void MemoryCommunication::get_value(byte dataType, byte *adress)
{
	for(byte i = 0; i< dataType; i++)
	{
		out_buffer[out_write_index++] = *adress;
		DEBUG("VALUE: %d\n\r", *adress);
	}
}

void MemoryCommunication::set_value(byte dataType, byte *adress)
{
	for(byte i = 0; i< dataType; i++)
	{
		*(adress-i) = in_buffer[i+5];
	}
}

void MemoryCommunication::reset(){
	in_count = 0;
	stop_index = STD_STOPINDEX;
}



